/* bug7.c

   An example of what happens when 10 threads stomp on each other
   when trying to update a counter

   In this example, 10 threads contribute to incrementing a counter.

   pthread.h should be first otherwise compile with -D_THREAD_SAFE 
*/
#include <pthread.h>
#include <stdio.h>
#include <sys/time.h>

#define NTHREADS 10

/* The PTHREAD_MUTEX_INITIALIZER macro initializes the static mutex, 
   setting its attributes to default values. This macro should only be used 
   for static mutexes, as no error checking is performed. */
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;

int counter = 0; 

void *thread_function(void *dummyPtr) {
   long i;
   printf("Thread number %x\n", pthread_self());
   for (i=0 ; i < 1000000 ; i++) {
		pthread_mutex_lock(&mutex1);
		counter++;
		pthread_mutex_unlock(&mutex1);
	}
   return NULL;
}

int main() {
   struct timeval tv1, tv2;
   struct timezone tz;
   pthread_t thread_id[NTHREADS];
   int i, j;

   gettimeofday(&tv1, &tz);

   for (i=0; i < NTHREADS; i++)
      pthread_create( &thread_id[i], NULL, thread_function, NULL );

   for (j=0; j < NTHREADS; j++)
      pthread_join( thread_id[j], NULL);

   gettimeofday(&tv2, &tz);

   /* Now that all threads are complete, print the final result which  */
   /* is wrong and print the time it took                              */
   printf("Total time: %f sec\n", (tv2.tv_usec-tv1.tv_usec)/1000000.0);
   printf("Final counter value: %d\n", counter);
}

